package by

import kotlin.properties.Delegates
import kotlin.reflect.KProperty

/**
 * 属性委托
 */
class ByExample {

    var p: String by Delegate()

    /**
     * 属性委托不需要实现任何接口，但需要提供getValue和setValue方法
     */
    class Delegate {
        operator fun getValue(thisRef: ByExample, property: KProperty<*>): String {
            return "$thisRef, thank you for delegating '${property.name}' to me!"
        }

        operator fun setValue(thisRef: ByExample, property: KProperty<*>, value: String) {
            println("$value has been assigned to '${property.name}' in $thisRef.")
        }
    }

}

/**
 * 标准委托
 */
object StandExample {

    /**
     * 可观察委托属性
     */
    var name: String by Delegates.observable("<no name>") { prop, old, new ->
        //当值放生变化时触发
        println("$old -> $new")
    }

    /**
     * 在函数或代码块内声明延迟委托属性
     */
    fun printLazyValue() {
        val lazyValue: String by lazy {
            //懒加载，只会打印一次computed!
            println("computed!")
            "Hello"
        }

        println(lazyValue)
        println(lazyValue)
    }

    /**
     * 可观察委托属性
     */
    fun printObservable() {
        println(name)
        name = "Observable"
        println(name)
    }
}

fun main(args: Array<String>) {
    val byExample = ByExample()
    println(byExample.p)
    byExample.p = "New"

    StandExample.printLazyValue()
    StandExample.printObservable()
}